home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************\
- * *
- * VFILE consists of 5 functions which simulate a "BASIC *
- * RANDOM FILE" structure using fixed length records of *
- * varying pre-specified size. A record may be up to 255 *
- * chars long. It is the programmer's responsibility to *
- * keep track of the contents of his record, and VFILE's *
- * responsibility to write and read the record to and from *
- * the correct position in file. Record numbers are *
- * maximum 32767. VFILE will give ERROR if reading past *
- * end of file or exceeding legal bounds. It will pad *
- * as-yet-unwritten internal records with nulls. An error *
- * is returned if there is not enough disk space for *
- * either the record or the padding. There is a sixth *
- * function (vset), which is used internally. *
- * *
- * The structure "_vbuf" must be included in the *
- * programme, and each file must reserve a VBUFSIZ area *
- * for buffering. This area will vary depending on NSECTS *
- * in BDSCIO.H THE VALUE OF NSECTS MUST BE GREATER *
- * THAN TWO. The definitions of _vbuf and VBUFSIZ *
- * should eventually find their way into BDSCIO.H *
- * I have included them in this source for clarity. *
- * *
- \************************************************************
-
-
-
-
- Version 1.0 by Greg Lister
-
- 19th November, 1980 */
-
-
-
-
- #include "bdscio.h"
- #define VBUFSIZ NSECTS * SECSIZ + 14
-
- struct _vbuf
- { int fd; /* File Descriptor */
- int eof; /* Actual EOF of file */
- int pos; /* Current record's position in buffer */
- int len; /* Record length */
- int sta; /* Start sector of buffer */
- int cnt; /* Number of sectors in buffer */
- int wflag; /* flag set if buffer written to */
- char buffer[NSECTS * SECSIZ];
- };
-
-
- vset(recno,vbuf)
- int recno;
- struct _vbuf *vbuf;
- /************************************************\
- * *
- * Sets up buffer for random reads and writes. *
- * Flushes buffer if necessary and fills buffer *
- * with required data. Sets pointer to beginning*
- * of r/w record. Fills unwritten buffer with *
- * nulls. Returns ERROR if cannot flush or *
- * if hard read error. Returns NULL if *
- * required buffer is not yet written. Returns *
- * -2 if required sector (128 byte) is not yet *
- * written. Else returns valid sectors in buf. *
- * *
- \************************************************/
- {
- int tmp,blkno,bss,blkoff,secno,bufsec,endrec;
-
- blkno=recno>>7; /* Block Number */
-
- bss=blkno*vbuf->len; /* Block start Sector */
-
- blkoff=(recno%128)*vbuf->len; /* Offset into Block */
-
- secno=bss+(blkoff>>7); /* Sector # of start of rec */
-
- endrec=bss+((blkoff+vbuf->len-1)>>7);/* Sec# END of rec */
-
- bufsec=(secno/(NSECTS-2))*(NSECTS-2); /* Start sec of buf */
-
- vbuf->pos=vbuf->buffer+((secno-bufsec)<<7)+(blkoff%128);
-
- if(bufsec!=vbuf->sta)
- { if(vbuf->wflag)
- { seek(vbuf->fd,vbuf->sta,0);
- if(write(vbuf->fd,vbuf->buffer,vbuf->cnt)<vbuf->cnt)
- return ERROR;
- if((tmp=tell(vbuf->fd))>vbuf->eof)
- vbuf->eof=tmp;
- vbuf->wflag=0;
- }
- if((vbuf->sta=bufsec)>vbuf->eof) return NULL;
- seek(vbuf->fd,bufsec,0);
- if((vbuf->cnt=read(vbuf->fd,vbuf->buffer,NSECTS))<0)
- return ERROR;
- if(vbuf->cnt!=NSECTS)
- fillb(vbuf->buffer+(vbuf->cnt<<7),
- vbuf->buffer+(NSECTS<<7),0,0);
- }
-
- if(endrec-bufsec>=vbuf->cnt) return -2;
- return vbuf->cnt;
- }
-
-
- vwrite(recno,vbuf,str)
- int recno;
- struct _vbuf *vbuf;
- char *str;
-
- /********************************************************\
- * *
- * Writes data at str to file vbuf at recno. Pads file *
- * with NULLS if skipping unwritten sections of file. *
- * Returns ERROR if full disk, unopened file etc *
- * Returns ERROR if bad record #; else returns OK *
- * *
- \********************************************************/
-
- { int tmp,tmp1,tmp2;
-
- if(recno<0) return ERROR;
- if((tmp=vset(recno,vbuf))==-1) return ERROR;
- if(tmp==0)
- { fillb(vbuf->buffer,NSECTS<<7,0,1);
- seek(vbuf->fd,vbuf->eof,0);
- while((vbuf->eof=tell(vbuf->fd))<vbuf->sta)
- if(write(vbuf->fd,vbuf->buffer,1)>1) return ERROR;
- }
- movmem(str,vbuf->pos,vbuf->len);
- tmp2=vbuf->buffer;
- tmp1=(127+vbuf->pos-tmp2+vbuf->len)>>7;
- if(tmp1>vbuf->cnt)
- vbuf->cnt=tmp1;
- vbuf->wflag=1;
- return OK;
- }
-
-
- vread(recno,vbuf,str)
- int recno;
- struct _vbuf *vbuf;
- char str[];
-
- /************************************************\
- * *
- * Reads record 'recno' from file to 'str'. *
- * Returns ERROR if hard error (unopened *
- * file etc) or if attempt is made to read *
- * past current end of file. Returns no of *
- * secs read in. ERROR if bad recno. *
- * *
- \************************************************/
-
- { int tmp;
- if(recno<0) return ERROR;
- tmp=vbuf->sta;
- if(vset(recno,vbuf)<1)
- {
- vbuf->sta=tmp;
- return ERROR;
- }
- movmem(vbuf->pos,str,vbuf->len);
- return vbuf->cnt;
- }
-
-
- vclose(vbuf)
- struct _vbuf *vbuf;
-
- /************************************************\
- * *
- * Closes file using vbuf. Returns OK if *
- * closed successfully. ERROR if error. *
- * *
- \************************************************/
-
- { if(vbuf->wflag)
- { seek(vbuf->fd,vbuf->sta,0);
- if(write(vbuf->fd,vbuf->buffer,vbuf->cnt)<0)
- return ERROR;
- }
- return close(vbuf->fd);
- }
-
-
-
- vopen(filename,vbuf,reclen)
- int reclen;
- char filename[];
- struct _vbuf *vbuf;
-
- /************************************************\
- * *
- * Opens filename for v-format buffered io *
- * Reclen is the specified record length *
- * (may be up to 255 chars). Vbuf is a *
- * VBUFSIZ buffer ((128 * NSECTS)+14) *
- * **NOTE** NSECTS must be 3 or more for this *
- * file structure to work. *
- * Returns ERROR if reclen is out of range *
- * or if open error occurs (ie file doesn't *
- * exist - use vcreat) *
- * *
- \************************************************/
-
- { if((vbuf->len=reclen)>255)return ERROR;
- if(reclen<0) return ERROR;
- if((vbuf->fd=open(filename,2))<0) return ERROR;
- vbuf->sta=vbuf->cnt=-1;
- vbuf->wflag=0;
- vbuf->pos=vbuf->buffer;
- vbuf->eof=telend(filename);
- return vbuf->fd;
- }
-
-
- vcreat(filename,vbuf,reclen)
- int reclen;
- char filename[];
- struct _vbuf *vbuf;
- /************************************************\
- * *
- * Creates a file as vopen (see above) *
- * *
- \************************************************/
- { fabort(creat(filename));
- return vopen(filename,vbuf,reclen);
- }
-
-
- /****************************************************\
- * *
- * The next function is general and not only a part *
- * of the VFILE package. It will tell you where the *
- * end of your file is to be found. *
- * *
- \****************************************************/
-
-
-
- telend(filename)
- char *filename;
- /************************************************\
- * *
- * returns number of last 128-byte record in *
- * file 'filename'. Returns NULL if file *
- * is either nonexistent or empty. *
- * *
- \************************************************/
- {
- int recnt;
- char fcb[38],ex;
- setfcb(fcb,filename);
- ex=recnt=0;
- while(1)
- { fcb[12]=ex++;
- if((bdos(15,fcb))==255) break;
- recnt+=fcb[15];
- }
- return recnt;
- }
-